3.7.2 对gb的介绍

gb是一个由Go社区成员开发的全新的构建工具。gb意识到,不一定要包装Go本身的工具,也可以使用其他方法来解决可重复构建的问题。

gb背后的原理源自理解到Go语言的 import 语句并没有提供可重复构建的能力。 import 语句可以驱动 go get ,但是 import 本身并没有包含足够的信息来决定到底要获取包的哪个修改的版本。 go get 无法定位待获取代码的问题,导致Go工具在解决重复构建时,不得不使用复杂且难看的方法。我们已经看到过使用 godep 时超长的导入路径是多么难看。

gb的创建源于上述理解。gb既不包装Go工具链,也不使用 GOPATH 。gb基于工程将Go工具链工作空间的元信息做替换。这种依赖管理的方法不需要重写工程内代码的导入路径。而且导入路径依旧通过 go getGOPATH 工作空间来管理。

让我们看看上一节的工程如何转换为gb工程,如代码清单3-12所示。

代码清单3-12  gb 工程的例子

/home/bill/devel/myproject ($PROJECT)
|-- src
|  |-- cmd
|  |  |-- myproject
|  |  |  |-- main.go
|  |-- examples
|  |-- model
|  |-- README.md
|-- vendor
  |-- src
    |-- bitbucket.org
    |  |-- ww
    |    |-- goautoneg
    |    |-- Makefile
    |    |-- README.txt
    |    |-- autoneg.go
    |    |-- autoneg_test.go
    |-- github.com
      |-- beorn7
        |-- perks
        |-- README.md
        |-- quantile
        |-- bench_test.go
    |-- example_test.go
    |-- exampledata.txt
    |-- stream.go

一个gb工程就是磁盘上一个包含 src/ 子目录的目录。符号 $PROJECT 导入了工程的根目录中,其下有一个 src/ 的子目录中。这个符号只是一个简写,用来描述工程在磁盘上的位置。 $PROJECT 不是必须设置的环境变量。事实上,gb根本不需要设置任何环境变量。

gb工程会区分开发人员写的代码和开发人员需要依赖的代码。开发人员的代码所依赖的代码被称作 第三方代码 (vendored code)。gb工程会明确区分开发人员的代码和第三方代码,如代码清单3-13和代码清单3-14所示。

代码清单3-13 工程中存放开发人员写的代码的位置

$PROJECT/src/

代码清单3-14 存放第三方代码的位置

$PROJECT/vendor/src/

gb 一个最好的特点是,不需要重写 导入 路径。可以看看这个工程里的main.go文件的 import 语句——没有任何需要为导入第三方库而做的修改,如代码清单3-15所示。

代码清单3-15 gb工程的导入路径

01 package main
02
03 import (
04   "bitbucket.org/ww/goautoneg"
05   "github.com/beorn7/perks"
06 )

gb工具首先会在 $PROJECT/src/ 目录中查找代码,如果找不到,会在 $PROJECT/vendor/src/ 目录里查找。与工程相关的整个源代码都会在同一个代码库里。自己写的代码在工程目录的 src/ 目录中,第三方依赖代码在工程目录的 vendor/src 子目录中。这样,不需要配合重写导入路径也可以完成整个构建过程,同时可以把整个工程放到磁盘的任意位置。这些特点,让gb成为社区里解决可重复构建的流行工具。

还需要提一点:gb工程与Go官方工具链(包括 go get )并不兼容。因为gb不需要设置 GOPATH ,而Go工具链无法理解gb工程的目录结构,所以无法用Go工具链构建、测试或者获取代码。构建(如代码清单3-16所示)和测试gb工程需要先进入 $PROJECT 目录,并使用gb工具。

代码清单3-16 构建gb工程

gb build all

很多Go工具支持的特性,gb都提供对应的特性。gb还提供了插件系统,可以让社区扩展支持的功能。其中一个插件叫作 vendor 。这个插件可以方便地管理 $PROJECT/vendor/src/ 目录里的依赖关系,而这个功能Go工具链至今没有提供。想了解更多gb的特性,可以访问这个网站:getgb.io。

results matching ""

    No results matching ""